import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 房间预定对话框
 * 
 * 这个对话框用于创建新的房间预定
 * 包含客人信息录入、房间选择、日期选择、费用计算等功能
 * 
 * 主要功能：
 * 1. 客人信息录入（姓名、身份证、电话、地址）
 * 2. 可用房间选择（只显示空闲房间）
 * 3. 入住和退房日期选择
 * 4. 自动计算预定费用
 * 5. 数据验证和保存
 * 
 * 业务流程：
 * 1. 用户填写客人信息
 * 2. 选择可用房间
 * 3. 选择入住日期和天数
 * 4. 系统自动计算费用
 * 5. 确认预定，保存数据
 * 6. 更新房间状态为"已预定"
 */
public class ReservationDialog extends JDialog {

    // ==================== 界面组件 ====================

    // 客人信息输入组件
    private JTextField guestIdField; // 客人ID（自动生成）
    private JTextField nameField; // 客人姓名
    private JTextField idCardField; // 身份证号
    private JTextField phoneField; // 联系电话
    private JTextField addressField; // 家庭地址

    // 预定信息输入组件
    private JComboBox<String> roomComboBox; // 房间选择下拉框
    private JSpinner daysSpinner; // 入住天数选择器
    private JLabel checkInDateLabel; // 入住日期显示
    private JLabel checkOutDateLabel; // 退房日期显示
    private JLabel totalAmountLabel; // 总金额显示

    // 日期相关
    private Date selectedCheckInDate; // 选择的入住日期
    private SimpleDateFormat dateFormat; // 日期格式化器

    // 对话框状态
    private boolean confirmed = false; // 是否确认预定

    /**
     * 构造方法 - 创建预定对话框
     * 
     * @param parent 父窗口，用于居中显示和模态设置
     */
    public ReservationDialog(JFrame parent) {
        // 调用父类构造方法，设置标题和模态
        super(parent, "房间预定", true);

        // 初始化日期格式化器
        dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        // 设置默认入住日期为今天
        selectedCheckInDate = new Date();

        // 设置界面
        setupUI();

        // 加载可用房间
        loadAvailableRooms();

        // 设置对话框居中显示
        setLocationRelativeTo(parent);
    }

    /**
     * 设置用户界面
     * 
     * 创建和布局所有的界面组件
     */
    private void setupUI() {
        // 设置对话框大小
        setSize(500, 700);
        setLayout(new BorderLayout());

        // 创建主面板
        JPanel mainPanel = new JPanel(new GridBagLayout());
        mainPanel.setBackground(Color.WHITE);
        mainPanel.setBorder(new EmptyBorder(20, 20, 20, 20));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(8, 8, 8, 8);
        gbc.anchor = GridBagConstraints.WEST;

        // ==================== 标题 ====================
        JLabel titleLabel = new JLabel("房间预定");
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
        titleLabel.setForeground(HotelManagementSystem.getPrimaryColor());
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 2;
        gbc.insets = new Insets(0, 0, 20, 0);
        mainPanel.add(titleLabel, gbc);

        // ==================== 客人信息区域 ====================
        gbc.gridwidth = 1;
        gbc.insets = new Insets(8, 8, 8, 8);

        // 客人ID（自动生成，不可编辑）
        JLabel guestIdLabel = new JLabel("客人ID:");
        guestIdLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 1;
        mainPanel.add(guestIdLabel, gbc);

        guestIdField = new JTextField(15);
        guestIdField.setFont(HotelManagementSystem.getButtonFont());
        guestIdField.setText(generateGuestId());
        guestIdField.setEditable(false);
        guestIdField.setBackground(Color.LIGHT_GRAY);
        gbc.gridx = 1;
        gbc.gridy = 1;
        mainPanel.add(guestIdField, gbc);

        // 客人姓名
        JLabel nameLabel = new JLabel("客人姓名:");
        nameLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 2;
        mainPanel.add(nameLabel, gbc);

        nameField = new JTextField(15);
        nameField.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 1;
        gbc.gridy = 2;
        mainPanel.add(nameField, gbc);

        // 身份证号
        JLabel idCardLabel = new JLabel("身份证号:");
        idCardLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 3;
        mainPanel.add(idCardLabel, gbc);

        idCardField = new JTextField(15);
        idCardField.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 1;
        gbc.gridy = 3;
        mainPanel.add(idCardField, gbc);

        // 联系电话
        JLabel phoneLabel = new JLabel("联系电话:");
        phoneLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 4;
        mainPanel.add(phoneLabel, gbc);

        phoneField = new JTextField(15);
        phoneField.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 1;
        gbc.gridy = 4;
        mainPanel.add(phoneField, gbc);

        // 家庭地址
        JLabel addressLabel = new JLabel("家庭地址:");
        addressLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 5;
        mainPanel.add(addressLabel, gbc);

        addressField = new JTextField(15);
        addressField.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 1;
        gbc.gridy = 5;
        mainPanel.add(addressField, gbc);

        // ==================== 预定信息区域 ====================

        // 分隔线
        JSeparator separator = new JSeparator();
        gbc.gridx = 0;
        gbc.gridy = 6;
        gbc.gridwidth = 2;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(20, 0, 20, 0);
        mainPanel.add(separator, gbc);

        gbc.gridwidth = 1;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = new Insets(8, 8, 8, 8);

        // 房间选择
        JLabel roomLabel = new JLabel("选择房间:");
        roomLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 7;
        mainPanel.add(roomLabel, gbc);

        roomComboBox = new JComboBox<>();
        roomComboBox.setFont(HotelManagementSystem.getButtonFont());
        roomComboBox.addActionListener(e -> updateTotalAmount());
        gbc.gridx = 1;
        gbc.gridy = 7;
        mainPanel.add(roomComboBox, gbc);

        // 入住日期选择
        JLabel checkInLabel = new JLabel("入住日期:");
        checkInLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 8;
        mainPanel.add(checkInLabel, gbc);

        JPanel datePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        datePanel.setBackground(Color.WHITE);

        checkInDateLabel = new JLabel(dateFormat.format(selectedCheckInDate));
        checkInDateLabel.setFont(HotelManagementSystem.getButtonFont());
        checkInDateLabel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(Color.GRAY),
                new EmptyBorder(5, 10, 5, 10)));
        datePanel.add(checkInDateLabel);

        JButton selectDateButton = createStyledButton("选择日期", HotelManagementSystem.getSecondaryColor());
        selectDateButton.addActionListener(e -> selectCheckInDate());
        datePanel.add(selectDateButton);

        gbc.gridx = 1;
        gbc.gridy = 8;
        mainPanel.add(datePanel, gbc);

        // 入住天数
        JLabel daysLabel = new JLabel("入住天数:");
        daysLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 9;
        mainPanel.add(daysLabel, gbc);

        daysSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 30, 1));
        daysSpinner.setFont(HotelManagementSystem.getButtonFont());
        daysSpinner.addChangeListener(e -> {
            updateCheckOutDate();
            updateTotalAmount();
        });
        gbc.gridx = 1;
        gbc.gridy = 9;
        mainPanel.add(daysSpinner, gbc);

        // 退房日期（自动计算）
        JLabel checkOutLabel = new JLabel("退房日期:");
        checkOutLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 10;
        mainPanel.add(checkOutLabel, gbc);

        checkOutDateLabel = new JLabel();
        checkOutDateLabel.setFont(HotelManagementSystem.getButtonFont());
        checkOutDateLabel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(Color.GRAY),
                new EmptyBorder(5, 10, 5, 10)));
        updateCheckOutDate();
        gbc.gridx = 1;
        gbc.gridy = 10;
        mainPanel.add(checkOutDateLabel, gbc);

        // 总金额
        JLabel amountLabel = new JLabel("预定金额:");
        amountLabel.setFont(HotelManagementSystem.getButtonFont());
        gbc.gridx = 0;
        gbc.gridy = 11;
        mainPanel.add(amountLabel, gbc);

        totalAmountLabel = new JLabel("¥0");
        totalAmountLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
        totalAmountLabel.setForeground(HotelManagementSystem.getAccentColor());
        gbc.gridx = 1;
        gbc.gridy = 11;
        mainPanel.add(totalAmountLabel, gbc);

        // ==================== 按钮面板 ====================
        JPanel buttonPanel = new JPanel(new FlowLayout());
        buttonPanel.setBackground(Color.WHITE);

        JButton confirmButton = createStyledButton("确认预定", HotelManagementSystem.getSuccessColor());
        confirmButton.addActionListener(new ConfirmActionListener());
        buttonPanel.add(confirmButton);

        JButton cancelButton = createStyledButton("取消", HotelManagementSystem.getAccentColor());
        cancelButton.addActionListener(e -> dispose());
        buttonPanel.add(cancelButton);

        gbc.gridx = 0;
        gbc.gridy = 12;
        gbc.gridwidth = 2;
        gbc.insets = new Insets(20, 0, 0, 0);
        mainPanel.add(buttonPanel, gbc);

        add(mainPanel, BorderLayout.CENTER);
    }

    /**
     * 加载可用房间到下拉框
     * 
     * 只显示状态为"空闲"的房间
     */
    private void loadAvailableRooms() {
        List<Room> rooms = DataManager.getInstance().getAllRooms();
        roomComboBox.removeAllItems();

        for (Room room : rooms) {
            if ("空闲".equals(room.getStatus())) {
                String roomInfo = room.getRoomNumber() + " - " + room.getRoomType() + " (¥" + room.getPrice() + "/晚)";
                roomComboBox.addItem(roomInfo);
            }
        }

        if (roomComboBox.getItemCount() == 0) {
            JOptionPane.showMessageDialog(this, "当前没有空闲房间可预定！", "提示", JOptionPane.WARNING_MESSAGE);
        } else {
            updateTotalAmount();
        }
    }

    /**
     * 选择入住日期
     * 
     * 弹出日期选择对话框
     */
    private void selectCheckInDate() {
        // 创建简单的日期选择对话框
        String dateStr = JOptionPane.showInputDialog(this,
                "请输入入住日期 (格式: yyyy-MM-dd):",
                dateFormat.format(selectedCheckInDate));

        if (dateStr != null && !dateStr.trim().isEmpty()) {
            try {
                Date newDate = dateFormat.parse(dateStr.trim());

                // 检查日期不能是过去的日期
                Date today = new Date();
                if (newDate.before(today)) {
                    JOptionPane.showMessageDialog(this, "入住日期不能是过去的日期！", "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }

                selectedCheckInDate = newDate;
                checkInDateLabel.setText(dateFormat.format(selectedCheckInDate));
                updateCheckOutDate();
                updateTotalAmount();

            } catch (Exception e) {
                JOptionPane.showMessageDialog(this, "日期格式错误！请使用 yyyy-MM-dd 格式", "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    /**
     * 更新退房日期
     * 
     * 根据入住日期和入住天数自动计算退房日期
     */
    private void updateCheckOutDate() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(selectedCheckInDate);
        cal.add(Calendar.DAY_OF_MONTH, (Integer) daysSpinner.getValue());

        checkOutDateLabel.setText(dateFormat.format(cal.getTime()));
    }

    /**
     * 更新总金额
     * 
     * 根据选择的房间和入住天数计算总费用
     */
    private void updateTotalAmount() {
        if (roomComboBox.getSelectedItem() != null) {
            String selectedRoom = (String) roomComboBox.getSelectedItem();
            String roomNumber = selectedRoom.split(" - ")[0];

            List<Room> rooms = DataManager.getInstance().getAllRooms();
            for (Room room : rooms) {
                if (room.getRoomNumber().equals(roomNumber)) {
                    int days = (Integer) daysSpinner.getValue();
                    double total = room.getPrice() * days;
                    totalAmountLabel.setText("¥" + total);
                    break;
                }
            }
        }
    }

    /**
     * 生成客人ID
     * 
     * 使用当前时间戳生成唯一的客人ID
     * 
     * @return 生成的客人ID
     */
    private String generateGuestId() {
        return "G" + System.currentTimeMillis();
    }

    /**
     * 生成预定ID
     * 
     * 使用当前日期和时间生成唯一的预定ID
     * 格式：R + yyyyMMdd + 时间戳后4位
     * 
     * @return 生成的预定ID
     */
    private String generateReservationId() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());
        String timeStr = String.valueOf(System.currentTimeMillis()).substring(6);
        return "R" + dateStr + timeStr;
    }

    /**
     * 创建样式化按钮
     * 
     * @param text            按钮文字
     * @param backgroundColor 背景颜色
     * @return 创建的按钮
     */
    private JButton createStyledButton(String text, Color backgroundColor) {
        JButton button = new JButton(text);
        button.setFont(HotelManagementSystem.getButtonFont());
        button.setBackground(backgroundColor);
        button.setForeground(Color.WHITE);
        button.setBorder(new EmptyBorder(8, 15, 8, 15));
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));

        // 添加鼠标悬停效果
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                button.setBackground(backgroundColor.darker());
            }

            public void mouseExited(java.awt.event.MouseEvent evt) {
                button.setBackground(backgroundColor);
            }
        });

        return button;
    }

    /**
     * 获取对话框是否确认
     * 
     * @return true表示用户确认了预定，false表示取消
     */
    public boolean isConfirmed() {
        return confirmed;
    }

    /**
     * 确认预定按钮的事件监听器
     */
    private class ConfirmActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // ==================== 数据验证 ====================

            // 验证客人姓名
            if (nameField.getText().trim().isEmpty()) {
                JOptionPane.showMessageDialog(ReservationDialog.this, "请输入客人姓名！", "提示", JOptionPane.WARNING_MESSAGE);
                nameField.requestFocus();
                return;
            }

            // 验证身份证号
            if (idCardField.getText().trim().isEmpty()) {
                JOptionPane.showMessageDialog(ReservationDialog.this, "请输入身份证号！", "提示", JOptionPane.WARNING_MESSAGE);
                idCardField.requestFocus();
                return;
            }

            // 验证电话号码
            if (phoneField.getText().trim().isEmpty()) {
                JOptionPane.showMessageDialog(ReservationDialog.this, "请输入联系电话！", "提示", JOptionPane.WARNING_MESSAGE);
                phoneField.requestFocus();
                return;
            }

            // 验证房间选择
            if (roomComboBox.getSelectedItem() == null) {
                JOptionPane.showMessageDialog(ReservationDialog.this, "请选择房间！", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            try {
                // ==================== 获取预定信息 ====================

                // 获取选择的房间信息
                String selectedRoom = (String) roomComboBox.getSelectedItem();
                String roomNumber = selectedRoom.split(" - ")[0];

                // 计算退房日期
                Calendar cal = Calendar.getInstance();
                cal.setTime(selectedCheckInDate);
                cal.add(Calendar.DAY_OF_MONTH, (Integer) daysSpinner.getValue());
                Date checkOutDate = cal.getTime();

                // 计算总金额
                List<Room> rooms = DataManager.getInstance().getAllRooms();
                double roomPrice = 0;
                for (Room room : rooms) {
                    if (room.getRoomNumber().equals(roomNumber)) {
                        roomPrice = room.getPrice();
                        break;
                    }
                }
                double totalAmount = roomPrice * (Integer) daysSpinner.getValue();

                // ==================== 创建数据对象 ====================

                // 创建客人信息
                Guest guest = new Guest(
                        guestIdField.getText().trim(),
                        nameField.getText().trim(),
                        idCardField.getText().trim(),
                        phoneField.getText().trim(),
                        addressField.getText().trim());

                // 创建预定记录
                Reservation reservation = new Reservation(
                        generateReservationId(),
                        guest.getGuestId(),
                        guest.getName(),
                        roomNumber,
                        dateFormat.format(selectedCheckInDate),
                        dateFormat.format(checkOutDate),
                        totalAmount,
                        "已预定");

                // ==================== 保存数据 ====================

                // 保存客人信息
                DataManager.getInstance().addGuest(guest);

                // 保存预定记录
                DataManager.getInstance().addReservation(reservation);

                // 更新房间状态为已预定
                DataManager.getInstance().updateRoomStatus(roomNumber, "已预定");

                // ==================== 显示成功信息 ====================

                confirmed = true;

                String successMessage = String.format(
                        "预定成功！\n\n" +
                                "预定号：%s\n" +
                                "客人：%s\n" +
                                "房间：%s\n" +
                                "入住日期：%s\n" +
                                "退房日期：%s\n" +
                                "总金额：¥%.2f",
                        reservation.getReservationId(),
                        guest.getName(),
                        roomNumber,
                        dateFormat.format(selectedCheckInDate),
                        dateFormat.format(checkOutDate),
                        totalAmount);

                JOptionPane.showMessageDialog(ReservationDialog.this, successMessage, "预定成功",
                        JOptionPane.INFORMATION_MESSAGE);
                dispose();

            } catch (Exception ex) {
                JOptionPane.showMessageDialog(ReservationDialog.this, "预定失败：" + ex.getMessage(), "错误",
                        JOptionPane.ERROR_MESSAGE);
                ex.printStackTrace();
            }
        }
    }
}